package com.logic.modular.gameCore.cultivate.exp;


import com.baomidou.mybatisplus.extension.service.IService;
import com.comment.pojo.domain.logic.core.CoreExperience;
import com.logic.modular.gameCore.cultivate.exp.mapper.CoreExperienceMapper;
import lombok.extern.slf4j.Slf4j;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import static com.logic.modular.gameCore.CoreCacheInfo.infoCache;


/**
 * 全局经验表(CoreExperience)表服务实现类
 *
 * @author cxy
 * @version 24.11.12.00
 * @since 2024-08-05 16:14:02
 */

@Slf4j
@Service
public class CoreExperienceServiceImpl extends ServiceImpl<CoreExperienceMapper, CoreExperience>
        implements IService<CoreExperience> , CoreExperienceService
{
    private static final Cache<String, Map<String, CoreExperience>> cache = Caffeine.newBuilder().build();
    private static final Cache<String, Map<Integer, Long>> experiencePool = Caffeine.newBuilder().build();

    @Resource
    private CoreExperienceMapper coreExperienceMapper;


    @PostConstruct
    private void init() {
        CoreExperience initSelect = CoreExperience.builder().build();
        List<CoreExperience> list = this.list(new LambdaQueryWrapper<>(initSelect));
        log.info("开始缓存全局经验表数据,数据量为:{}", list.size());
        cache.put(
                "coreExperience",
                list.stream().collect(Collectors.toMap(item -> item.getLevel() + "-" + item.getType(), CoreExperience -> CoreExperience))
        );
        log.info("全局经验表数据缓存完成");
        initializeExperiencePool(list);
    }

    private void initializeExperiencePool(List<CoreExperience> list) {
        log.info("开始初始化经验池");
        Map<Integer, List<CoreExperience>> collect = list.stream().collect(Collectors.groupingBy(CoreExperience::getType));
        collect.forEach((type, value) -> {
            Map<Integer, Long> experiencePoolItem = new HashMap<>();
            long pool = 0;
            experiencePoolItem.put(1, pool);// 初始化等级
            for (CoreExperience coreExperience : value) {
                pool += coreExperience.getExp();
                experiencePoolItem.put(coreExperience.getLevel() + 1, pool);
            }
            experiencePool.put(String.format("experiencePool:%d", type), experiencePoolItem);
            String info = String.format("类型:%d,总经验需要%d,共计:%d级", type, pool, value.size());
            log.info(info);
        });
    }

    /**
     * 获取经验池
     *
     * @param type 1:武将 2:主公
     * @return 经验池
     */
    public static Map<Integer, Long> obtainExperiencePool(Integer type) {
        return experiencePool.getIfPresent(String.format("experiencePool:%d", type));
    }

    public static int obtainLeave(Integer type, long hasExp) {
        Map<Integer, Long> integerLongMap = obtainExperiencePool(type);
        int leave = 0;
        for (int i = 1; i < integerLongMap.size(); i++) {
            Long v = integerLongMap.get(i);
            if (hasExp < v) {
                leave = i - 1;
                break;
            }
        }
        return leave;
    }

    public static Long obtainNextLeaveExp(Integer type, Integer leave) {
        Map<Integer, Long> ifPresent = experiencePool.getIfPresent(String.format("experiencePool:%d", type));
        return Objects.requireNonNull(ifPresent).get(leave);
    }


    public List<CoreExperience> listCache() {
        Map<String, CoreExperience> values = cache.getIfPresent("coreExperience");
        if (Objects.isNull(values)) {
            throw new RuntimeException("全局经验表数据为空");
        }
        return new ArrayList<>(values.values());
    }

    public Map<String, CoreExperience> mapCache() {
        Map<String, CoreExperience> values = cache.getIfPresent("coreExperience");
        if (Objects.isNull(values)) {
            throw new RuntimeException("全局经验表数据为空");
        }
        return values;
    }

    public static CoreExperience getCache(Integer level, Integer type) {
        Map<String, CoreExperience> values = cache.getIfPresent("coreExperience");
        if (Objects.isNull(values)) {
            throw new RuntimeException("全局经验表数据为空");
        }
        return values.get(level + "-" + type);
    }

    @Override
    public Integer getMaxLevel(int type) {
        String key = String.format("%s:%d", "maxLevel", type);
        Integer maxLevel = (Integer) infoCache.getIfPresent(key);
        if (maxLevel == null) {
            maxLevel = coreExperienceMapper.getMaxLevel(type);
            infoCache.put(key, maxLevel);
        }
        return maxLevel;
    }
}
